package model

import (
	"database/sql"
	"github.com/jmoiron/sqlx"
	"zimuzu_cvn_web_api/config"
	"zimuzu_cvn_web_api/pkg/e"
	"zimuzu_cvn_web_api/pkg/errno"
)

// 全网收益能力
// Auth: hzp
func GetGlobalCapacity() (globalCapacity, lastGlobalCapacity float64, err error) {

	// 全网最近7天的平均收益能力
	err = sqlx.Get(config.C.DB.DB, &globalCapacity, "SELECT IFNULL(SUM(cvn)/count(*), 0.00) FROM mg_node_payment WHERE "+
		" `pledge_status`=1 and `type` in (1,2) and `date` >= DATE_FORMAT(DATE_SUB(NOW(), INTERVAL 7 DAY),'%Y-%m-%d') ")
	if err != nil {
		return globalCapacity, lastGlobalCapacity, err
	}

	// 全网昨天的平均收益能力
	err = sqlx.Get(config.C.DB.DB, &lastGlobalCapacity, "SELECT IFNULL(SUM(cvn)/count(*), 0.00) FROM mg_node_payment WHERE "+
		" `pledge_status`=1 and `type` in (1,2) and `date` >= DATE_FORMAT(DATE_SUB(NOW(), INTERVAL 1 DAY),'%Y-%m-%d') ")
	if err != nil {
		return globalCapacity, lastGlobalCapacity, err
	}

	if lastGlobalCapacity <= 0 {
		lastGlobalCapacity = globalCapacity
	}

	// 开启事务
	conn, err := config.C.DB.DB.Begin()
	if err != nil {
		return globalCapacity, lastGlobalCapacity, err
	}

	var rowId2, rowId3 int64

	r2, err2 := conn.Exec("UPDATE global_var SET value = ?, update_time=UNIX_TIMESTAMP( NOW()) WHERE name = 'income_ability'", globalCapacity)
	if err2 == nil {
		rowId2, err2 = r2.RowsAffected()
		if err2 != nil {
			rowId2 = 0
		}
		if err2 == nil && rowId2 == 0 {
			rowId2 = 1
		} else {
		}
	} else {
		e.Log("err", err2.Error())
		rowId2 = 0
	}

	r3, err3 := conn.Exec("UPDATE global_var SET value = ?, update_time=UNIX_TIMESTAMP( NOW()) WHERE name = 'last_income_ability'", lastGlobalCapacity)
	if err3 == nil {
		rowId3, err3 = r3.RowsAffected()
		if err3 != nil {
			rowId3 = 0
			e.Log("err", "err33333")
		}
		if err3 == nil && rowId3 == 0 {
			rowId3 = 1
		}
	} else {
		e.Log("err", err3.Error())
		rowId3 = 0
	}

	// 提交事务
	if rowId2 > 0 && rowId3 > 0 {
		err = conn.Commit()
		if err != nil {
			_ = conn.Rollback()
			return globalCapacity, lastGlobalCapacity, errno.RollBackErr
		}
		return globalCapacity, lastGlobalCapacity, nil
	} else {
		e.Log("err", "rowId1=", rowId2, " &rowId3=", rowId3)
		_ = conn.Rollback()
		return globalCapacity, lastGlobalCapacity, errno.RollBackErr
	}
}

// 统计指定用户的挖矿能力
// 参数：globalCapacity 最近七天全网平均收益
// 参数：lastGlobalCapacity 昨天全网平均收益
// Auth: hzp
func GetSuperMinerMiningCapacity(uid int64, lastGlobalCapacity float64) (err error) {

	// 参数：
	// capacity：最近7天该用户平均收益能力
	// lastCapacity：昨天该用户平均收益能力
	// lastInComePayment：用于结算租借令牌收益能力
	var capacity, lastCapacity, lastInComePayment float64

	// 最近7天的收益能力
	err = sqlx.Get(config.C.DB.DB, &capacity, "SELECT IFNULL(SUM(cvn)/count(*), 0.00) FROM mg_node_payment WHERE "+
		" uid = ? and `pledge_status`=1 and `date` >= DATE_FORMAT(DATE_SUB(NOW(), INTERVAL 7 DAY),'%Y-%m-%d') ", uid)
	if err != nil {
		return err
	}
	// 昨天的收益能力
	err = sqlx.Get(config.C.DB.DB, &lastCapacity, "SELECT IFNULL(SUM(cvn)/count(*), 0.00) FROM mg_node_payment WHERE "+
		" uid = ? and `pledge_status`=1 and `date` >= DATE_FORMAT(DATE_SUB(NOW(), INTERVAL 1 DAY),'%Y-%m-%d') ", uid)
	if err != nil {
		return err
	}

	if lastCapacity < lastGlobalCapacity {
		lastInComePayment = lastGlobalCapacity
	} else {
		lastInComePayment = lastCapacity
	}

	// 开启事务
	conn, err := config.C.DB.DB.Begin()
	if err != nil {
		return err
	}
	var rowId1 int64
	r1, err1 := conn.Exec("UPDATE super_node_miner SET income_ability = ?, last_income_ability = ?,"+
		" last_income_payment =?  WHERE uid = ?", capacity, lastCapacity, lastInComePayment, uid)
	if err1 == nil {
		rowId1, err1 = r1.RowsAffected()
		if err1 != nil {
			rowId1 = 0
		}
		if err1 == nil && rowId1 == 0 {
			rowId1 = 1
		}
	} else {
		e.Log("info", err1.Error())
		rowId1 = 0
	}

	// 提交事务
	if rowId1 > 0 {
		err = conn.Commit()
		if err != nil {
			_ = conn.Rollback()
			return errno.RollBackErr
		}
		return nil
	} else {
		_ = conn.Rollback()
		return errno.RollBackErr
	}
}

// 发放CVNT阶段
func MgUserPaymentUpdateStatus(Uid, LxLogId int64, Way int, cvnt float64) (err error) {

	return nil
	// 循环用户
	// 1、更新用户账目表 cvn_log
	// 2、请求总账目接口 user_amount
	// 3、更新流水表
	// 4、更新 状态

	// 1、获取总账目记录
	//timeNowInt64 := time.Now().Unix()
	//UserAmount, err := Get
	//if err != nil {
	//	return err
	//}
	//
	//tag := 0
	//Source := 0
	//if Way == 1 {
	//	Source = 27
	//} else if Way == 2 {
	//	Source = 12
	//} else if Way == 3 {
	//	Source = 2
	//} else if Way == 4 {
	//	Source = 12
	//} else if Way == 5 {
	//	Source = 36 // 令牌出租收益
	//} else if Way == 6 {
	//	if UserAmount.UnWithDrawnCvn+cvnt >= 0 {
	//		Source = 37 // 令牌租用扣款
	//	} else if UserAmount.UnWithDrawnCvn <= 0 {
	//		tag = 1
	//		if UserAmount.TokenSellPledgingCvn+cvnt < 0 {
	//			return errno.PledgedUnEnoughErr
	//		}
	//		Source = 38 // 系统扣除保证金
	//	} else {
	//		if UserAmount.TokenSellPledgingCvn+cvnt < 0 {
	//			return errno.PledgedUnEnoughErr
	//		}
	//		tag = 2
	//	}
	//} else {
	//	return errno.AgainErr
	//}
	//
	//// 开启事务
	//conn, err := config.C.DB.DB.Begin()
	//if err != nil {
	//	return err
	//}
	//var rowId1, rowId2, rowId3 int64
	//
	//// 1、更新用户账目表 cvn_log
	//if math.Abs(cvnt) > 0 {
	//	if tag == 0 {
	//		validityExpire := timeNowInt64 + 180*e.TimeFormatDay
	//		r1, err1 := conn.Exec("INSERT INTO cvn_log (`uid`, `lx_log_id`, `cvn`, `total_gain_cvn`, `unwithdrawn_cvn`, `validity_expire`, `source`, `expire_status`,"+
	//			" `use_status`, `create_time`, `update_time`) VALUES (?, ?, ?, ?, ?, ?, ?, 1, 1, ?, ? )", Uid, LxLogId, cvnt, UserAmount.TotalGainCvn,
	//			UserAmount.UnWithDrawnCvn, validityExpire, Source, timeNowInt64, timeNowInt64)
	//		if err1 == nil {
	//			rowId1, err1 = r1.RowsAffected()
	//		}
	//	} else if tag == 1 {
	//		// TODO 账号余额为0，直接扣除保证金
	//		validityExpire := timeNowInt64 + 180*e.TimeFormatDay
	//		r1, err1 := conn.Exec("INSERT INTO cvn_log (`uid`, `lx_log_id`, `cvn`, `total_gain_cvn`, `unwithdrawn_cvn`, `validity_expire`, `source`, `expire_status`,"+
	//			" `use_status`, `create_time`, `update_time`) VALUES (?, ?, ?, ?, ?, ?, ?, 1, 1, ?, ? )", Uid, LxLogId, cvnt, UserAmount.TotalGainCvn,
	//			0.00, validityExpire, Source, timeNowInt64, timeNowInt64)
	//		if err1 == nil {
	//			rowId1, err1 = r1.RowsAffected()
	//		}
	//	} else if tag == 2 {
	//		// TODO 可用余额大于0，但不足已支付租用收益 需要额外扣除部分先从保证金划转过来，再一起扣除
	//		validityExpire := timeNowInt64 + 180*e.TimeFormatDay
	//		r1, err1 := conn.Exec("INSERT INTO cvn_log (`uid`, `cvn`, `total_gain_cvn`, `unwithdrawn_cvn`, "+
	//			" `validity_expire`, `source`, `expire_status`, `use_status`, `create_time`, `update_time`) VALUES "+
	//			" (?, ?, ?, ?, ?, ?, 1, 1, ?, ?), (?, ?, ?, ?, ?, ?, 1, 1, ?, ?);",
	//			Uid, -cvnt-UserAmount.UnWithDrawnCvn, UserAmount.TotalGainCvn, 0.00, validityExpire, 38,
	//			timeNowInt64, timeNowInt64,
	//			Uid, cvnt, UserAmount.TotalGainCvn, 0.00, validityExpire, 37,
	//			timeNowInt64, timeNowInt64)
	//		if err1 == nil {
	//			rowId1, err1 = r1.RowsAffected()
	//		}
	//	} else {
	//		return errno.ParamsError
	//	}
	//} else {
	//	rowId1 = 1
	//}
	//
	//// 2、更新总账目 user_amount
	//if cvnt == 0 {
	//	rowId2 = 1
	//} else {
	//	if tag == 0 {
	//		totalCvnt := UserAmount.TotalGainCvn + cvnt
	//		unWithdrawnCvn := UserAmount.UnWithDrawnCvn + cvnt
	//		r2, err2 := conn.Exec("UPDATE user_amount SET `total_gain_cvn` = ?, `unwithdrawn_cvn` = ?, `withdraw_cvn` = ?, "+
	//			" update_time = ? Where uid = ?", totalCvnt, unWithdrawnCvn, UserAmount.UnWithDrawnCvn, timeNowInt64, Uid)
	//		if err2 == nil {
	//			rowId2, err2 = r2.RowsAffected()
	//		} else {
	//			rowId2 = 0
	//		}
	//	} else {
	//		totalCvnt := UserAmount.TotalGainCvn + cvnt
	//		unWithdrawnCvn := UserAmount.UnWithDrawnCvn + cvnt
	//		if unWithdrawnCvn >= 0 {
	//			// 可用余额 足够发
	//			r2, err2 := conn.Exec("UPDATE user_amount SET `total_gain_cvn` = ?, `unwithdrawn_cvn` = ?, `withdraw_cvn` = ?, "+
	//				" update_time = ? Where uid = ?", totalCvnt, unWithdrawnCvn, UserAmount.UnWithDrawnCvn, timeNowInt64, Uid)
	//			if err2 == nil {
	//				rowId2, err2 = r2.RowsAffected()
	//			} else {
	//				rowId2 = 0
	//			}
	//		} else {
	//			// 可用余额 不够发
	//			unWithdrawnCvn := UserAmount.TokenSellPledgingCvn + UserAmount.UnWithDrawnCvn + cvnt
	//			r2, err2 := conn.Exec("UPDATE user_amount SET `total_gain_cvn` = ?, `unwithdrawn_cvn` = 0.00, `withdraw_cvn` = ?, "+
	//				"token_sell_pledging_cvn =?, update_time = ? Where uid = ?", totalCvnt, UserAmount.UnWithDrawnCvn, unWithdrawnCvn,
	//				timeNowInt64, Uid)
	//			if err2 == nil {
	//				rowId2, err2 = r2.RowsAffected()
	//			} else {
	//				rowId2 = 0
	//			}
	//		}
	//	}
	//}
	//
	//// 3、更新发放状态
	//r3, err3 := conn.Exec("UPDATE mg_user_payment SET `status` = 3 WHERE id = ? AND `status` = 2", LxLogId)
	//if err3 == nil {
	//	rowId3, err3 = r3.RowsAffected()
	//}
	//
	//// 提交事务
	//if rowId1 > 0 && rowId2 > 0 && rowId3 > 0 && err3 == nil {
	//	err = conn.Commit()
	//	if err != nil {
	//		_ = conn.Rollback()
	//		return errno.RollBackErr
	//	}
	//	e.Log("info", "用户【", Uid, "/ type =", Way, "】发放CVNT完成")
	//	return nil
	//} else {
	//	_ = conn.Rollback()
	//	e.Log("err", "用户【", Uid, "/ type =", Way, "】发放CVNT失败: {rowId1=", rowId1, "&rowId2=", rowId2, "&rowId3=", rowId3)
	//	return errno.RollBackErr
	//}
}

// 获取需要补发CVN的数据
type FixedNodePayment struct {
	ID         int64  `db:"id" json:"id"`
	UID        int64  `db:"uid" json:"uid"`
	Date       string `db:"date" json:"date"`
	SN         string `db:"sn" json:"sn"`
	Type       int    `db:"type" json:"type"`
	OnlineTime int    `db:"online_time" json:"online_time"`
}

func UpdateUserPayment(db sqlx.Execer, logId int64) (err error) {
	_, err = db.Exec("UPDATE mg_user_payment SET `status` = 3 WHERE id = ?  AND `status` = 2", logId)
	if err != nil {
		return err
	}
	return
}

// 需要补缴保证金的用户列表
// Auth: hzp
func GetNeedTokenPledgingCvn() (res []UidList, err error) {
	err = sqlx.Select(config.C.DB.DB, &res, "SELECT distinct use_uid AS uid FROM mg_token WHERE rent_status =2 group by use_uid ")
	if err != nil {
		return res, err
	}
	return res, nil
}

// 获取进行中的订单
func GetUserStartingOrder(uid int64) (orderNoList []string, err error) {

	err = sqlx.Select(config.C.DB.DB, &orderNoList, "SELECT distinct order_no FROM mg_token_sell_order WHERE lend_uid = ? AND status NOT in (4, 5)", uid)
	if err != nil {
		return orderNoList, err
	}
	return
}

func GetMgTokenListByUserId(uid int64) (tokenIds []int64, err error) {

	err = sqlx.Select(config.C.DB.DB, &tokenIds, "SELECT id FROM mg_token WHERE use_uid = ? AND `rent_status` = 2", uid)
	if err != nil {
		return tokenIds, err
	}

	return tokenIds, nil
}

// 解绑 释放令牌数据 并记录日志
// UpdateStatus = 4, 5 更新为 到期、终止
// Auth: hzp
func UnbindMgTokenAndLog(tokenId int64, UpdateStatus int) (err error) {

	if tokenId == 0 {
		return errno.ParamsError
	}

	// 1、更新令牌表记录 mg_token
	// 2、写日志        mg_token_log

	// 开启事务
	conn, err := config.C.DB.DB.Begin()
	if err != nil {
		return err
	}
	var rowId1, rowId2 int64

	// 1、更新令牌表记录 mg_token
	r1, err1 := conn.Exec("UPDATE mg_token SET `status`=1, `rent_status`=1, `rent_days`=0, rent_scale=0.00, "+
		" rent_time=0,use_uid=0 Where id = ?", tokenId)
	if err1 == nil {
		rowId1, err1 = r1.RowsAffected()
	} else {
		rowId1 = 0
	}

	// 2、写日志 mg_token_log
	r2, err2 := conn.Exec("INSERT INTO mg_token_log(`token_id`,`source_uid`,`target_uid`,`order_no`,`type`,"+
		"`create_time`) VALUES (?, 0, 0, ?, ?, unix_timestamp(now()))", tokenId, "", UpdateStatus)
	if err2 == nil {
		rowId2, err2 = r2.RowsAffected()
	} else {
		rowId2 = 0
	}

	// 提交事务
	if rowId1 > 0 && rowId2 > 0 {
		err = conn.Commit()
		if err != nil {
			_ = conn.Rollback()
			return errno.RollBackErr
		}
		return nil
	} else {
		_ = conn.Rollback()
		return errno.RollBackErr
	}
}

// 更新令牌数据并记录日志
// UpdateStatus = 4, 5 更新为 到期、终止
// Auth: hzp
func UpdateMgTokenAndLog(orderNo string, UpdateStatus int, uid int64) (err error) {

	// 1、更新令牌表记录           mg_token
	// 2、写日志                  mg_token_log
	// 3、更新订单状态             mg_token_sell_order
	// 4、终止的时候更新违规次数    super_node_miner

	// 开启事务
	conn, err := config.C.DB.DB.Begin()
	if err != nil {
		return err
	}
	var rowId3, rowId4 int64

	// 3、更新订单状态 mg_token_sell_order
	r3, err3 := conn.Exec("UPDATE mg_token_sell_order SET `status` = ? Where order_no = ?", UpdateStatus, orderNo)
	if err3 == nil {
		rowId3, err3 = r3.RowsAffected()
	} else {
		rowId3 = 0
	}

	// 4、终止的时候更新违规次数
	if UpdateStatus == 5 {
		r4, err4 := conn.Exec("UPDATE super_node_miner SET bad_records = bad_records + 1 WHERE uid = ?", uid)
		if err4 == nil {
			rowId4, err4 = r4.RowsAffected()
		} else {
			rowId4 = 0
		}
	} else {
		rowId4 = 1
	}

	// 提交事务
	if rowId3 > 0 && rowId4 > 0 {
		err = conn.Commit()
		if err != nil {
			_ = conn.Rollback()
			return errno.RollBackErr
		}
		return nil
	} else {
		_ = conn.Rollback()
		return errno.RollBackErr
	}
}

// 获取代发放记录表
func GetTokenPaymentNeedData() (err error) {

	var count int
	err = sqlx.Get(config.C.DB.DB, &count, "SELECT count(*) FROM mg_token_payment WHERE `date`= DATE_SUB(CURDATE(),INTERVAL 1 DAY)")
	if err != nil {
		return err
	}
	if count > 0 {
		return errno.RecordError
	}

	// 1、写入记录表             mg_token_payment
	// 2、写入待发放记录表        mg_user_payment
	// 3、写入扣借令牌人的记录    mg_user_payment

	// 开启事务
	conn, err := config.C.DB.DB.Begin()
	if err != nil {
		return err
	}
	var rowId1, rowId2, rowId3 int64

	// 1、写入记录表 mg_token_payment
	r1, err1 := conn.Exec("INSERT INTO mg_token_payment(`date`, node_id, token_id, belong_uid, use_uid, create_time, rent_scale, cvn) " +
		" SELECT t4.`date`, IFNULL(t3.node_id, 0), t4.id, t4.belong_uid, t4.use_uid, t4.`time`, t4.rent_scale, t4.last_income_payment FROM" +
		" (SELECT DATE_SUB(CURDATE(),INTERVAL 1 DAY) AS `date`, t1.id AS id, t1.belong_uid  AS belong_uid, " +
		" t1.use_uid AS use_uid, UNIX_TIMESTAMP(NOW()) AS `time`, t1.rent_scale AS rent_scale, " +
		" IFNULL(t2.last_income_payment, 0.00) AS last_income_payment FROM mg_token AS t1 LEFT JOIN super_node_miner AS t2 " +
		" ON t1.use_uid = t2.uid WHERE t1.rent_status = 2 AND t1.belong_uid <> 0 AND t1.use_uid <> 0 AND " +
		" t1.rent_time <= UNIX_TIMESTAMP( DATE_ADD(DATE_SUB(CURDATE(),INTERVAL 1 DAY),INTERVAL 10 HOUR) ) ) AS t4 " +
		" LEFT JOIN mg_node AS t3 ON t4.id = t3.token_id AND t3.status = 1 AND t3.token_status > 1 WHERE 1 GROUP BY id ASC ")
	if err1 == nil {
		rowId1, err1 = r1.RowsAffected()
		if err1 != nil {
			e.Log("err", err1.Error())
		}
	} else {
		e.Log("err", err1.Error())
		rowId1 = 0
	}

	// 2、写入待发放记录表 mg_user_payment
	r2, err2 := conn.Exec("INSERT INTO mg_user_payment(`uid`,`up`,`cvnt`,`status`,`date`,`type`,`create_time`) " +
		" SELECT belong_uid, 0.00, IFNULL(SUM(cvn * rent_scale) / 100, 0.00), 2, DATE_SUB(CURDATE(),INTERVAL 1 DAY)," +
		" 5, UNIX_TIMESTAMP(NOW()) FROM mg_token_payment WHERE `date`= DATE_SUB(CURDATE(),INTERVAL 1 DAY) GROUP BY belong_uid")
	if err2 == nil {
		rowId2, err2 = r2.RowsAffected()
		if err2 != nil {
			e.Log("err", "2.1", err2.Error())
		}
	} else {
		e.Log("err", "2.2", err2.Error())
		rowId2 = 0
	}

	// 3、写入扣借令牌人的记录 mg_user_payment
	r3, err3 := conn.Exec("INSERT INTO mg_user_payment(`uid`,`up`,`cvnt`,`status`,`date`,`type`,`create_time`) " +
		" SELECT use_uid, 0.00, - ABS( IFNULL(SUM(cvn * rent_scale) / 100, 0.00) ), 2, DATE_SUB(CURDATE(),INTERVAL 1 DAY)," +
		" 6, UNIX_TIMESTAMP(NOW()) FROM mg_token_payment WHERE `date`= DATE_SUB(CURDATE(),INTERVAL 1 DAY) GROUP BY use_uid")
	if err3 == nil {
		rowId3, err3 = r3.RowsAffected()
		if err3 != nil {
			e.Log("err", "3.1", err3.Error())
		}
	} else {
		e.Log("err", "3.2", err3.Error())
		rowId3 = 0
	}

	// 提交事务
	if rowId1 > 0 && rowId2 > 0 && rowId3 > 0 {
		err = conn.Commit()
		if err != nil {
			_ = conn.Rollback()
			return errno.RollBackErr
		}
		return nil
	} else {
		_ = conn.Rollback()
		return errno.RollBackErr
	}
}

type NodeIDParams struct {
	Uid    int64 `form:"uid" json:"uid" db:"uid"`
	NodeId int64 `form:"node_id" json:"node_id" db:"node_id"`
}

// 获取到 超级结点列表
func GetSuperUserList() (re []NodeIDParams, err error) {

	err = sqlx.Select(config.C.DB.DB, &re, "SELECT uid, node_id FROM super_node WHERE 1")
	if err != nil {
		return re, err
	}
	return
}

// 获取到 已发放用户数据
func GetSuperPaymentBySuperNodeId(SuperNodeId int64) (res float64, err error) {

	var superCvn float64
	// linux 收益
	err = sqlx.Get(config.C.DB.DB, &superCvn, "SELECT IFNULL(SUM(`super_cvn`), 0.00) FROM mg_node_payment WHERE super_node_id = ? AND "+
		" `date` = DATE_SUB(CURDATE(),INTERVAL 1 DAY) AND `status` = 1", SuperNodeId)
	if err == sql.ErrNoRows {
		superCvn = 0.00
	}
	if err != nil {
		return res, err
	}

	return superCvn, nil
}

// 第三批路由器补贴
func AddNodePaymentForSub(Uid int64) (err error) {

	// 判断是否重复发放
	count := 0
	if Uid > 0 {
		err = sqlx.Get(config.C.DB.DB, &count, "SELECT count(*) FROM mg_node_payment where create_time >="+
			" UNIX_TIMESTAMP(DATE_ADD(CURDATE(),INTERVAL -DAY(CURDATE())+1 DAY)) and create_time <"+
			" UNIX_TIMESTAMP(DATE_ADD(CURDATE()-DAY(CURDATE())+1,INTERVAL 1 MONTH)) AND type = 4 AND uid = ?;", Uid)
	} else {
		err = sqlx.Get(config.C.DB.DB, &count, "SELECT count(*) FROM mg_node_payment where create_time >="+
			" UNIX_TIMESTAMP(DATE_ADD(CURDATE(),INTERVAL -DAY(CURDATE())+1 DAY)) and create_time <"+
			" UNIX_TIMESTAMP(DATE_ADD(CURDATE()-DAY(CURDATE())+1,INTERVAL 1 MONTH)) AND type = 4;")
	}
	if err != nil {
		return err
	}
	if count > 0 {
		return errno.AgainErr
	}

	// 开启事务
	conn, err := config.C.DB.DB.Begin()
	if err != nil {
		return err
	}

	var rowId1, rowId2 int64

	// 写入节点数据
	if Uid > 0 {
		r1, err1 := conn.Exec("INSERT INTO mg_node_payment (`date`,`node_id`,`uid`,`up`,`type`,`status`,`create_time`,`cvn`) "+
			" SELECT CURDATE(),`node_id`,`uid`,0.00, 4, 0, UNIX_TIMESTAMP(NOW()), 200.00 FROM mg_node where batch = 3 AND uid = ?", Uid)
		if err1 == nil {
			rowId1, err1 = r1.RowsAffected()
		} else {
			rowId1 = 0
		}
	} else {
		r1, err1 := conn.Exec("INSERT INTO mg_node_payment (`date`,`node_id`,`uid`,`up`,`type`,`status`,`create_time`,`cvn`) " +
			" SELECT CURDATE(),`node_id`,`uid`,0.00, 4, 0, UNIX_TIMESTAMP(NOW()), 200.00 FROM mg_node where batch = 3")
		if err1 == nil {
			rowId1, err1 = r1.RowsAffected()
		} else {
			rowId1 = 0
		}
	}

	// 汇总流量数据以用户纬度
	if Uid > 0 {
		r2, err2 := conn.Exec("INSERT INTO mg_user_payment (`date`,`type`,`lx_count_id`,`uid`,`up`,`status`,`cvnt`,`create_time`) "+
			" SELECT CURDATE(),4,0,`uid`,0.00,2,sum(cvn),UNIX_TIMESTAMP(NOW()) FROM mg_node_payment where type = 4 AND "+
			" create_time>=UNIX_TIMESTAMP(DATE_ADD(CURDATE(),INTERVAL -DAY(CURDATE())+1 DAY)) and create_time < "+
			" UNIX_TIMESTAMP(DATE_ADD(CURDATE()-DAY(CURDATE())+1,INTERVAL 1 MONTH) )"+
			" AND status = 0 AND uid = ?", Uid)
		if err2 == nil {
			rowId2, err2 = r2.RowsAffected()
		} else {
			rowId2 = 0
		}
	} else {
		r2, err2 := conn.Exec("INSERT INTO mg_user_payment (`date`,`type`,`lx_count_id`,`uid`,`up`,`status`,`cvnt`,`create_time`) " +
			" SELECT CURDATE(),4,0,`uid`,0.00,2,sum(cvn),UNIX_TIMESTAMP(NOW()) FROM mg_node_payment where type = 4 AND " +
			" create_time>=UNIX_TIMESTAMP(DATE_ADD(CURDATE(),INTERVAL -DAY(CURDATE())+1 DAY)) and create_time < " +
			" UNIX_TIMESTAMP(DATE_ADD(CURDATE()-DAY(CURDATE())+1,INTERVAL 1 MONTH) )" +
			" AND status = 0 and uid > 0 group by uid DESC")
		if err2 == nil {
			rowId2, err2 = r2.RowsAffected()
		} else {
			rowId2 = 0
		}
	}

	// 提交事务
	if rowId1 > 0 && rowId2 > 0 {
		err = conn.Commit()
		if err != nil {
			_ = conn.Rollback()
			return errno.RollBackErr
		}
		e.Log("info", "第三批路由器补发数据统计完成")
		return nil
	} else {
		_ = conn.Rollback()
		return errno.RollBackErr
	}
}

// 获取用户的超级结点数据
func GetSuperNodeMinerByUid(Uid int64) (SuperNodeId int64, err error) {
	err = sqlx.Get(config.C.DB.DB, &SuperNodeId, "SELECT super_node_id FROM super_node_miner WHERE uid = ? AND `status` = 20", Uid)
	if err == sql.ErrNoRows {
		return 0, nil
	}
	if err != nil {
		return 0, err
	}
	return SuperNodeId, nil
}

// 更新 super_node_payment 表
func InsertSuperNodePayment(conn sqlx.Execer, NodeId int64, Cvn float64) (err error) {
	r3, err := conn.Exec("INSERT INTO super_node_payment (`node_id`, `date`, `type`, `create_time`, `cvnt`) "+
		" VALUES (?, DATE_SUB(CURDATE(),INTERVAL 1 DAY), ?, unix_timestamp(now()), ?)", NodeId, 10, Cvn)
	if err == nil {
		_, err = r3.LastInsertId()
	}
	return err
}
